<template>
  <div class="webgl-turtle">
    <h1>海龟绘图</h1>
    <p>使用WebGL实现海龟绘图功能，展示动态绘制正方形的动画效果。</p>

    <el-card class="demo-section">
      <template #header>
        <div class="card-header">
          <h3>海龟绘图展示</h3>
        </div>
      </template>
      <div class="demo-content">
        <canvas ref="demoCanvas" width="400" height="300"></canvas>
        <div class="control-panel">
          <el-form :model="turtleForm" label-width="100px">
            <el-form-item label="动画延迟">
              <el-slider
                v-model="turtleForm.animationDelay"
                :min="100"
                :max="1000"
                :step="100"
              />
            </el-form-item>
            <el-form-item label="线条颜色">
              <el-color-picker v-model="turtleForm.color" @change="updateColor" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="startAnimation">刷新动画</el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
    </el-card>

    <el-card class="code-section">
      <template #header>
        <div class="card-header">
          <h3>命令说明</h3>
        </div>
      </template>
      <div class="code-content">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="forward (fd) n">
            向前移动n个单位
          </el-descriptions-item>
          <el-descriptions-item label="backward (bk) n">
            向后移动n个单位
          </el-descriptions-item>
          <el-descriptions-item label="right (rt) angle">
            向右转动angle度
          </el-descriptions-item>
          <el-descriptions-item label="left (lt) angle">
            向左转动angle度
          </el-descriptions-item>
          <el-descriptions-item label="penup (pu)">
            提起画笔，移动时不绘制
          </el-descriptions-item>
          <el-descriptions-item label="pendown (pd)">
            放下画笔，移动时绘制线条
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { WebGLUtils } from '@/utils/webgl'
import { Turtle } from '@/utils/turtle'

const demoCanvas = ref<HTMLCanvasElement | null>(null)
const gl = ref<WebGLRenderingContext | null>(null)
const shaderProgram = ref<WebGLProgram | null>(null)
const webglUtils = ref<WebGLUtils | null>(null)
const turtle = ref<Turtle | null>(null)

const turtleForm = reactive({
  animationDelay: 300,
  color: '#ff0000' // 默认红色
})

// 初始化WebGL
const initWebGL = () => {
  if (!demoCanvas.value) return

  gl.value = demoCanvas.value.getContext('webgl')
  if (!gl.value) {
    console.error('Failed to get WebGL context')
    return
  }

  webglUtils.value = new WebGLUtils(gl.value)

  const vertexShader = webglUtils.value.createShader(gl.value.VERTEX_SHADER, `
    attribute vec4 a_Position;
    void main() {
      gl_Position = a_Position;
      gl_PointSize = 1.0;
    }
  `)
  const fragmentShader = webglUtils.value.createShader(gl.value.FRAGMENT_SHADER, `
    precision mediump float;
    uniform vec4 u_Color;
    void main() {
      gl_FragColor = u_Color;
    }
  `)
  if (!vertexShader || !fragmentShader) return

  shaderProgram.value = webglUtils.value.createProgram(vertexShader, fragmentShader)
  if (!shaderProgram.value) return

  gl.value.useProgram(shaderProgram.value)
  // 设置默认颜色
  const colorLoc = gl.value.getUniformLocation(shaderProgram.value, 'u_Color')
  const { r, g, b } = hexToRgb(turtleForm.color)
  gl.value.uniform4f(colorLoc, r, g, b, 1.0)

  turtle.value = new Turtle(gl.value, shaderProgram.value)

  gl.value.viewport(0, 0, demoCanvas.value.width, demoCanvas.value.height)
  gl.value.clearColor(0.0, 0.0, 0.0, 1.0)
  gl.value.clear(gl.value.COLOR_BUFFER_BIT)
  startAnimation()
}

// 开始动画
const startAnimation = () => {
  if (!turtle.value) return
  turtle.value.clear()
  turtle.value.animate(360 * 3, turtleForm.animationDelay)
}

// 更新颜色
const updateColor = (color: string) => {
  if (!gl.value || !shaderProgram.value) return
  const colorLoc = gl.value.getUniformLocation(shaderProgram.value, 'u_Color')
  const { r, g, b } = hexToRgb(color)
  gl.value.uniform4f(colorLoc, r, g, b, 1.0)
}

// 辅助函数：将十六进制颜色转换为RGB
const hexToRgb = (hex: string) => {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
  return result ? {
    r: parseInt(result[1], 16) / 255,
    g: parseInt(result[2], 16) / 255,
    b: parseInt(result[3], 16) / 255
  } : { r: 0, g: 0, b: 0 }
}

// 组件挂载时初始化WebGL
onMounted(() => {
  initWebGL()
})
</script>

<style lang="scss" scoped>
.webgl-turtle {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;

  h1 {
    color: #303133;
    margin-bottom: 20px;
  }

  p {
    margin-bottom: 30px;
  }

  .demo-section,
  .code-section {
    margin: 30px 0;

    .card-header {
      display: flex;
      align-items: center;

      h3 {
        margin: 0;
        color: #409EFF;
      }
    }
  }

  .demo-section {
    .demo-content {
      display: flex;
      gap: 20px;

      canvas {
        border: 1px solid #dcdfe6;
        background-color: #000;
      }

      .control-panel {
        flex: 1;
        padding: 20px;
        background-color: #f8f9fa;
        border-radius: 4px;
      }
    }
  }

  .code-section {
    .code-content {
      background-color: #f8f9fa;
      padding: 15px;
      border-radius: 4px;
    }
  }
}
</style>
